package java_thinking.unit_18_IO._18_10;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

/**
 * @Desc:   对映射文件的部分加锁
 *          1.文件映射通常用于极大的文件，我们对其部分进行加锁，其余部分任能够被其他进程使用，例如数据库就是这样的，多个
 *            用户可以同时访问它
 *          2.java虚拟机会自动释放锁，或者关闭加锁的通道，不过也可以使用FileLock.release()来释放锁
 *
 * @author: cww
 * @DateTime: 2019-05-18 14:43
 */

public class LockingMapped {
    static int LENGTH = 0x8FFFFFF;
    static FileChannel fc;
    private static String file1 = "src/maindemo/java/java_thinking/unit_18_IO/_18_10/LargeMappedFiles.txt";
    public static void main(String[] args) throws IOException {
        fc = new RandomAccessFile(file1, "rw").getChannel();
        MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, LENGTH);
        for (int i = 0; i < LENGTH; i++) {
            out.put((byte)'x');
        }

    }
    private static class LockAndModify extends Thread {
        private ByteBuffer buff;
        private int start , end;

        /**
         * 创建了缓冲区和用于修改的slice()
         */
        LockAndModify(ByteBuffer mbb, int start, int end) {
            this.start = start;
            this.end = end;
            mbb.limit(end);
            mbb.position(start);
            buff = mbb.slice();
            start();
        }

        /**
         * 获得文件通道上的锁(我们不能获得缓冲器上的锁，只能是通道上的)
         * lock()调用类似于获得一个对象的线程锁：我们现在处在"临界区"，既对该部分的文件具有独占访问权；
         */
        @Override
        public void run() {
            try {
                FileLock fl = fc.lock(start, end, false);
                System.out.println("Locked: " + start + " to " + end);
                while (buff.position() < buff.limit() - 1) {
                    buff.put((byte)(buff.get() + 1));
                }
                fl.release();
                System.out.println("Released: " + start + " to " +end);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
